const NAMESPACE = '@@loading';

const createLoadingPlugin = ({
  namespace = NAMESPACE,
  observe = []
} = {}) => {
  return store => {
    if (store.state[namespace]) {
      throw new Error(
        `createLoadingPlugin: ${namespace} exited in current store`
      );
    }

    store.registerModule(namespace, {
      namespaced: true,
      state: {
        global: false,
        effects: {}
      },
      mutations: {
        SHOW(state, { payload }) {
          state.global = true;
          state.effects = {
            ...state.effects,
            [payload]: true,
          }
        },
        HIDE(state, { payload }) {
          state.global = false;
          state.effects = {
            ...state.effects,
            [payload]: false,
          }
        }
      }
    });

    store.subscribeAction({
      before: action => {
        if (shouldEffect(action, observe)) {
          store.commit({ type: namespace + '/SHOW', payload: action.type });
        }
      },
      after: action => {
        if (shouldEffect(action, observe)) {
          store.commit({ type: namespace + '/HIDE', payload: action.type });
        }
      }
    });
  };
};

function shouldEffect({ type }, observe) {
  if (observe.length === 0) {
    return true;
  }
  return observe.indexOf(type) > -1;
}

export default createLoadingPlugin;
